package common

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	rand1 "crypto/rand"
	"crypto/sha256"
	"encoding/base64"
	"errors"
	"io"
	"math/rand"
	"time"
)

// =============================================AES,对称性加密===============================================================

var key = []byte("gba-pwd-666-asdfqwer-pwd")

// 生成随机密钥（32 字节，用于 AES-256）
func generateKey() ([]byte, error) {
	key1 := make([]byte, 32)
	_, err := rand.Read(key1)
	if err != nil {
		return nil, err
	}
	return key1, nil
}

// 加密函数，确保输出长度为 25 位
func Encrypt(key []byte, plaintext string) (string, error) {
	// 创建 AES 加密块
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}

	// 将明文填充到块大小的倍数
	plaintextBytes := []byte(plaintext)
	plaintextBytes = pad(plaintextBytes, aes.BlockSize)

	// 创建初始化向量 (IV)
	ciphertext := make([]byte, aes.BlockSize+len(plaintextBytes))
	iv := ciphertext[:aes.BlockSize]
	if _, err := io.ReadFull(rand1.Reader, iv); err != nil {
		return "", err
	}

	// 使用 CBC 模式加密
	mode := cipher.NewCBCEncrypter(block, iv)
	mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintextBytes)

	// 将加密结果编码为 Base64
	//encryptedBase64 := base64.StdEncoding.EncodeToString(ciphertext)

	// 如果长度超过 25，截取前 25 位；如果不足 25，填充到 25 位
	//if len(encryptedBase64) > 25 {
	//	return encryptedBase64[:25], nil
	//} else if len(encryptedBase64) < 25 {
	//	return encryptedBase64 + GeneratePadding(25-len(encryptedBase64)), nil
	//}
	return base64.StdEncoding.EncodeToString(ciphertext), nil
}

// 解密函数
func Decrypt(key []byte, encryptedBase64 string) (string, error) {
	// 解码 Base64
	ciphertext, err := base64.StdEncoding.DecodeString(encryptedBase64)
	if err != nil {
		return "", err
	}

	// 检查密文长度
	if len(ciphertext) < aes.BlockSize {
		return "", errors.New("ciphertext too short")
	}

	// 提取初始化向量 (IV)
	iv := ciphertext[:aes.BlockSize]
	ciphertext = ciphertext[aes.BlockSize:]

	// 创建 AES 解密块
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}

	// 使用 CBC 模式解密
	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(ciphertext, ciphertext)

	// 去除填充
	plaintextBytes := unpad(ciphertext)
	return string(plaintextBytes), nil
}

// 填充函数（PKCS7 填充）
func pad(data []byte, blockSize int) []byte {
	padding := blockSize - len(data)%blockSize
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(data, padText...)
}

// 去除填充
func unpad(data []byte) []byte {
	padding := int(data[len(data)-1])
	return data[:len(data)-padding]
}

// =============================================哈希,只加不解============================================================
// 生成随机盐值
func GenerateSalt(length int) string {
	const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	rand.Seed(time.Now().UnixNano())
	salt := make([]byte, length)
	for i := range salt {
		salt[i] = charset[rand.Intn(len(charset))]
	}
	return string(salt)
}

// 使用 SHA-256 加密密码（密码 + 盐值），并返回固定长度为 25 的 Base64 字符串
func HashPassword(password, salt string) string {
	// 将密码和盐值拼接
	passwordWithSalt := password + salt

	// 计算 SHA-256 哈希值
	hash := sha256.Sum256([]byte(passwordWithSalt))

	// 将哈希值转换为 Base64 字符串
	hashBase64 := base64.StdEncoding.EncodeToString(hash[:])

	// 如果长度超过 25，截取前 25 位；如果不足 25，填充到 25 位
	if len(hashBase64) > 25 {
		return hashBase64[:25]
	} else if len(hashBase64) < 25 {
		return hashBase64 + GenerateSalt(25-len(hashBase64))
	}
	return hashBase64
}

// 验证密码
func VerifyPassword(inputPassword, storedHash, salt string) bool {
	// 对输入的密码进行相同的哈希处理
	inputHash := HashPassword(inputPassword, salt)

	// 比较存储的哈希值和输入的哈希值
	return inputHash == storedHash
}

// 验证密码
func VerifyPasswordNew(inputPassword, storedHash string, salt []byte) bool {
	// 对输入的密码进行相同的哈希处理
	input, _ := Decrypt(salt, storedHash)

	// 比较存储的哈希值和输入的哈希值
	return input == inputPassword
}
